package com.csw.shuanfa.utils.request;

import com.alibaba.fastjson.JSONObject;
import com.csw.shuanfa.entity.User;
import com.google.gson.Gson;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/suanfa/request")
public class RequestTestController {
    private static final ConcurrentHashMap mapRequest = new ConcurrentHashMap();

    /**
     * 转对象
     * 方法1,适合form-date 请求，左边一个json,右边是一个大括号包一个对象字段的字符串
     *
     * @param request
     */
    @RequestMapping(value = "/test1", method = RequestMethod.POST)
    public void test1(HttpServletRequest request) {


        /**
         *
         方法1,适合form-date 请求，左边一个json,右边是一个大括号包一个对象字段的字符串
         */
        String json = request.getParameter("json");
        User user = (User) new Gson().fromJson(json, User.class);
        String username1 = user.getName();

        /**
         * 获取文件 form-data请求   左边是file 右边是文件
         */
        MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
        //接受多个文件
        MultiValueMap<String, MultipartFile> multiFileMap = multipartHttpServletRequest.getMultiFileMap();
        //接受单个文件
        MultipartFile file = multipartHttpServletRequest.getFile("file");
        if (!file.isEmpty()) {
            String name = file.getName();
        }


    }

    /**
     * http://localhost:8080/suanfa/request/test2
     * {
     * "name":"aa",
     * "cc":"cc2"
     * }
     * 转对象,推荐
     * 方法2，适合raw-json请求，直接一个大括号包一个对象字段的字符串
     *
     * @param request
     */
    @RequestMapping(value = "/test2", method = RequestMethod.POST)
    public void test2(HttpServletRequest request) throws Exception {


        /**
         * 写法一，变成可读请求进行重复读
         * 方法2，适合raw-json请求，直接一个大括号包一个对象字段的字符串
         */
        // 使用ReReadableHttpServletRequest包装原始的HttpServletRequest对象

        JSONObject object = getRequestString(request);
        JSONObject object1 = getRequestString(request);
        JSONObject object2 = getRequestString(request);
        String username2 = object != null ? object.getString("name") : "";


    }

    /**
     * http://localhost:8080/suanfa/request/test3
     * {
     * "name":"aa",
     * "cc":"cc3"
     * }
     * 转对象,推荐
     * 方法2，适合raw-json请求，直接一个大括号包一个对象字段的字符串
     *
     * @param request
     */
    @RequestMapping(value = "/test3", method = RequestMethod.POST)
    public void test3(HttpServletRequest request) throws Exception {


        /**
         * 写法一，变成可读请求进行重复读
         * 方法2，适合raw-json请求，直接一个大括号包一个对象字段的字符串
         */
        // 使用ReReadableHttpServletRequest包装原始的HttpServletRequest对象

        JSONObject object = getRequestString(request);
        JSONObject object1 = getRequestString(request);
        JSONObject object2 = getRequestString(request);
        String username2 = object != null ? object.getString("name") : "";
    }

    private byte[] getRequestBody(HttpServletRequest request) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        try (InputStream inputStream = request.getInputStream()) {
            byte[] data = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(data)) != -1) {
                buffer.write(data, 0, bytesRead);
            }
        }
        return buffer.toByteArray();
    }


    /**
     * 直接拿单个字符串对象
     * 一个流只能读一次,解决重复读取问题
     *
     * @param request
     */
    public static JSONObject getRequestString(HttpServletRequest request) throws Exception {
        String key = request.getRequestURI();
        if (mapRequest.get(key) == null) {
            request = new ReReadableHttpServletRequest(request);
            mapRequest.put(key, request);
        } else {
            request = (HttpServletRequest) mapRequest.get(key);
        }

        BufferedReader reader = null;
        InputStream inputStream = request.getInputStream();
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
            String line;
            StringBuffer buffer = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            JSONObject jsonObject = JSONObject.parseObject(buffer.toString());
            return jsonObject;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {

            if (reader != null) {
                reader.close();
            }
        }
    }

}
